package com.ruoyi.shangpinxinxi.controller;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ruoyi.shangpinxinxi.domain.Shangpinxinxi;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class tiaoMaAuto {
    // 二维码尺寸
    private static final int QRCODE_SIZE = 350;
    // 用二维码生成新图片，新图片加高多少，比如加的字体大小为24，这里就设置成26
    private static int FONT_SIZE_HEIGHT = 30;
    // 用二维码生成新图片，宽度
    private static final int BUFFEREDIMAGE_SIZE_WIDTH = QRCODE_SIZE;
    // 用二维码生成新图片，高度
    private static final int BUFFEREDIMAGE_SIZE_HEIGHT = QRCODE_SIZE + FONT_SIZE_HEIGHT;

    //private static final String filePath = "C:/ruoyi/uploadPath/upload/ChuKuDan/";
    //private static final String filePath = "D:/";
    private static final String filePath = "C:/ruoyi/uploadPath/upload/TiaoMa/";

    public static void main(String[] args) {
       /* String content = "https://image.baidu.com/search/detail?ct=503316480&z=&tn=baiduimagedetail&ipn=d&word=%E5%A3%81%E7%BA%B8&step_word=&ie=utf-8&in=&cl=2&lm=-1&st=-1&hd=undefined&latest=undefined&copyright=undefined&cs=2544377084,275372641&os=3052229399,834441112&simid=3533086814,586585425&pn=59&rn=1&di=72930&ln=3476&fr=&fmq=1526269427171_R&fm=&ic=0&s=undefined&se=&sme=&tab=0&width=&height=&face=undefined&is=0,0&istype=2&ist=&jit=&bdtype=0&spn=0&pi=0&gsm=0&objurl=https%3A%2F%2Fss0.baidu.com%2F-Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F0e2442a7d933c895ca486665d51373f0820200fd.jpg&rpstart=0&rpnum=0&adpicid=0&nojc=undefined";//二维码内容
        int width = 888;//二维码宽度
        int height = 888;//二维码高度
        int margin = 3;//二维码边距

        //String filePath = "D:\\";//二维码保存路径
        String fileName = "高清壁纸，你值得拥有！";//二维码文件名
        String formatName = "jpg";//二维码图片格式

        try {
            // 生成二维码
            if(createQRCode(content, width, height,margin,filePath, fileName, formatName)) {
                System.out.println("Yes");
                return;
            }
            System.out.println("No");
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        Shangpinxinxi shangpinxinxi = new Shangpinxinxi();
        shangpinxinxi.setId(1L);
        shangpinxinxi.setShangpinName(null);
        shangpinxinxi.setShangpinLeibie("防火锁");
        shangpinxinxi.setGuiGeKuan("1480");
        shangpinxinxi.setGuiGeGao("2080");
        shangpinxinxi.setKaiXiang("外双开");
        shangpinxinxi.setShangpinShoujia(String.valueOf(new BigDecimal(277)));
        shangpinxinxi.setBeizhu("");
        //System.out.println(TiaoXingMa(shangpinxinxi));
        // 保存图片 JPEG表示保存格式
        try {
                ImageIO.write(createTheQRCode(shangpinxinxi), "JPEG", new FileOutputStream("D:/a.jpg"));
            } catch (NoSuchAlgorithmException | IOException e) {
                e.printStackTrace();
            }
    }

    public static String QRCote(Shangpinxinxi shangpinxinxi){
        String md54name = null;
        try {
            String text = shangpinxinxi.getShangpinName() +
                    "_" +
                    shangpinxinxi.getShangpinLeibie() +
                    "_" +
                    shangpinxinxi.getGuiGeKuan() +
                    "_" +
                    shangpinxinxi.getGuiGeGao();
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                // 将要加密的文本转换为字节数组，然后更新Digest对象
                md.update(text.getBytes());

                // 计算最终的摘要结果，返回值为一个字节数组
                byte[] digest = md.digest();

                // 将字节数组转换为16进制字符串
                StringBuilder sb = new StringBuilder();
                for (byte b : digest) {
                    sb.append(String.format("%02x", b));
                }
                md54name = sb.toString();
                ImageIO.write(createTheQRCode(shangpinxinxi), "JPEG",
                        new FileOutputStream(filePath +
                                md54name+".jpg"));
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "https://www.beilianjd.com:2560/profile/upload/TiaoMa/"+md54name+".jpg";
    }

    public static String TiaoXingMa(Shangpinxinxi shangpinxinxi){
        String md54name = null;
        try {
            String text = shangpinxinxi.getShangpinName() +
                    "_" +
                    shangpinxinxi.getShangpinLeibie() +
                    "_" +
                    shangpinxinxi.getGuiGeKuan() +
                    "_" +
                    shangpinxinxi.getGuiGeGao();
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                // 将要加密的文本转换为字节数组，然后更新Digest对象
                md.update(text.getBytes());

                // 计算最终的摘要结果，返回值为一个字节数组
                byte[] digest = md.digest();

                // 将字节数组转换为16进制字符串
                StringBuilder sb = new StringBuilder();
                for (byte b : digest) {
                    sb.append(String.format("%02x", b));
                }
                md54name = sb.toString();
                ImageIO.write(createTheTiaoXingMa(shangpinxinxi), "JPEG",
//                        new FileOutputStream(filePath +
//                                md54name+".jpg")
                        new FileOutputStream("D:/a.jpg")
                );
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "http://120.78.175.194:2560/profile/upload/TiaoMa/"+md54name+".jpg";
    }

    private static BufferedImage createTheTiaoXingMa(Shangpinxinxi shangpinxinxi) {
        String content = shangpinxinxi.getShangpinLeibie();
        if (shangpinxinxi.getShangpinName() == null) {
            content +="；"+shangpinxinxi.getGuiGeKuan()
                    +"X"+ shangpinxinxi.getGuiGeGao()+
                    "；"+ shangpinxinxi.getKaiXiang();
        }else {
            content+="；名："+shangpinxinxi.getShangpinName()
                    +"；"+shangpinxinxi.getGuiGeKuan()
                    +"X"+ shangpinxinxi.getGuiGeGao()+
                    "；"+ shangpinxinxi.getKaiXiang();
        }

        String contentUnicode = toUnicode(content);
        System.out.println(content);
        System.out.println(contentUnicode);
        // 设置参数
        MultiFormatWriter writer = new MultiFormatWriter();
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = writer.encode(contentUnicode, BarcodeFormat.CODE_128, 350, 100);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        // 设置位矩阵转图片的参数
        MatrixToImageConfig config = new MatrixToImageConfig(Color.black.getRGB(), Color.white.getRGB());
        // 位矩阵对象转BufferedImage对象
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, config);
//        try {
//            ImageIO.write(bufferedImage, "JPEG",
//    //                        new FileOutputStream(filePath +
//    //                                md54name+".jpg")
//                    new FileOutputStream("D:/b.jpg")
//            );
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        return addNote(bufferedImage,content);
    }

    private static BufferedImage createTheQRCode(Shangpinxinxi shangpinxinxi) throws NoSuchAlgorithmException {
        // 二维码基本参数设置
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        // 设置编码字符集utf-8
        //hints.put(EncodeHintType.CHARACTER_SET, CharacterSetECI.UTF8);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //hints.put(EncodeHintType.CHARACTER_SET, "GBK");
        // 设置纠错等级L/M/Q/H,当二维码被损毁一部分时，纠错等级越高，越可能读取成功；同样的，纠错等级越高，单位面积内点阵的点越多，机器扫描时，识别所需时间越长，当前设置等级为最高等级H
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 可设置范围为0-10，但仅四个变化0 1(2) 3(4 5 6) 7(8 9 10)
        hints.put(EncodeHintType.MARGIN, 0);

        // 生成图片类型为QRCode
        BarcodeFormat format = BarcodeFormat.QR_CODE;
        // 创建位矩阵对象
        BitMatrix matrix = null;

        String content = "商品类别："+ shangpinxinxi.getShangpinLeibie();
        if (shangpinxinxi.getShangpinName() == null) {
            content +="；规格："+shangpinxinxi.getGuiGeKuan()
                    +"X"+ shangpinxinxi.getGuiGeGao()+
                    "；开向："+ shangpinxinxi.getKaiXiang();
        }else {
            content+="；商品名称："+shangpinxinxi.getShangpinName()
                    +"；规格："+shangpinxinxi.getGuiGeKuan()
                    +"X"+ shangpinxinxi.getGuiGeGao()+
                    "；开向："+ shangpinxinxi.getKaiXiang();
        }

        String contentUnicode =bianhaoSet(shangpinxinxi);
        try {
            // 生成二维码对应的位矩阵对象
            matrix = new MultiFormatWriter().encode(contentUnicode, format, QRCODE_SIZE, QRCODE_SIZE, hints);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        // 设置位矩阵转图片的参数
        MatrixToImageConfig config = new MatrixToImageConfig(Color.black.getRGB(), Color.white.getRGB());
        // 位矩阵对象转BufferedImage对象
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(matrix, config);

        return addNote(bufferedImage,content);
    }

    public static String bianhaoSet(Shangpinxinxi shangpinxinxi) throws NoSuchAlgorithmException {
        String contentUnicode = shangpinxinxi.getShangpinBianhao();
        if (contentUnicode == null) {
            String text = shangpinxinxi.getShangpinName() +
                    "_" +
                    shangpinxinxi.getShangpinLeibie() +
                    "_" +
                    shangpinxinxi.getGuiGeKuan() +
                    "_" +
                    shangpinxinxi.getGuiGeGao();
            MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(text.getBytes());

                // 计算最终的摘要结果，返回值为一个字节数组
                byte[] digest = md.digest();

                // 将字节数组转换为16进制字符串
                StringBuilder sb = new StringBuilder();
                for (byte b : digest) {
                    sb.append(String.format("%02x", b));
                }
                contentUnicode = sb.toString().substring(0,10);
        }
        return contentUnicode;
    }

    /**
     * 将字符串转换为Unicode码，
     * 返回一个以\\u开头的十六进制数字字符串，如"\u0048\u0065\u006c\u006c\u006f\u0020\u4e16\u754c\u0021"
     */
    public static String toUnicode(String str) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c < 128) { // 对 ASCII 字符直接取值
                sb.append(c);
            } else { // 将其他字符转换为 Unicode 编码
                sb.append("\\u").append(String.format("%04x", (int) c));
            }
        }
        return sb.toString();
    }

    /**
     * 将Unicode码字符串转换为字符串
     */
    public static String fromUnicode(String unicodeStr) {
        StringBuilder sb = new StringBuilder();
        String[] codes = unicodeStr.split("\\\\u");
        for (int i = 1; i < codes.length; i++) { // 注意从下标为 1 的元素开始处理，因为第一个元素为空字符串
            if (!codes[i].isEmpty()) {
                int codePoint = Integer.parseInt(codes[i], 16);
                if (codePoint < 128) { // 对 ASCII 字符直接解码
                    sb.append((char) codePoint);
                } else { // 对非 ASCII 字符进行转码
                    sb.append(Character.toChars(codePoint));
                }
            }
        }
        return sb.toString();
    }

    /**
     * 给二维码下方添加说明文字
     * @param image 原二维码
     * @param note 说明文字
     * @return 带说明文字的二维码
     */
    private static BufferedImage addNote(BufferedImage image,String note){
        Image src = image.getScaledInstance(QRCODE_SIZE, QRCODE_SIZE,Image.SCALE_DEFAULT);
        BufferedImage tag;

        Font font = new Font("微软雅黑",Font.BOLD,24);

        // 创建一个临时图片，用于计算字体宽度和高度
        BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = img.createGraphics();
        g2d.setFont(font);
        FontMetrics fm = g2d.getFontMetrics();  // 获取字体信息
        Rectangle2D rect = fm.getStringBounds(note, g2d);  // 计算文字的矩形边界大小
        int width = (int) -Math.ceil(rect.getY());  // 取整，得出字体宽度
        int height = (int) Math.ceil(rect.getHeight());  // 取整，得出字体高度
        g2d.dispose();  // 释放资源

        //System.out.println("字号为 " + font.getSize() + " 的宋体汉字对应的宽度为：" + width + " 像素，高度为：" + height + " 像素");

        int zilen = 10;
        FONT_SIZE_HEIGHT = height+2;

        //新图片变大多少取决于下方文字的数量
        int con2len = note.length()%zilen;
        int conrow = note.length()/zilen;
        if (con2len > 0) {
            conrow+=1;
        }
        int margin;
        if (note.length() > zilen) {
            margin = (BUFFEREDIMAGE_SIZE_WIDTH - (zilen*width))/2;
        }else {
            margin = (BUFFEREDIMAGE_SIZE_WIDTH - (note.length()*width))/2;
        }

        if (note.length()<=zilen){
            //生成新图片的大小
            tag = new BufferedImage(BUFFEREDIMAGE_SIZE_WIDTH, BUFFEREDIMAGE_SIZE_HEIGHT,BufferedImage.TYPE_INT_RGB);
        }else{
            //这句代码还没调试过，这里表示文字需要折行
            tag = new BufferedImage(BUFFEREDIMAGE_SIZE_WIDTH, QRCODE_SIZE+(FONT_SIZE_HEIGHT*conrow),BufferedImage.TYPE_INT_RGB);
        }
        //设置低栏白边
        Graphics g1 = tag.getGraphics();
        //设置文字
        Graphics2D g2 = tag.createGraphics();

        g1.setColor(Color.WHITE);
        g2.setFont(font);
        g2.setColor(Color.BLACK);
        if (note.length()<=zilen) {
            //下面这个26要和tag = new BufferedImage(330, 356,BufferedImage.TYPE_INT_RGB);356-330=26对上
            g1.fillRect(0, QRCODE_SIZE, QRCODE_SIZE, FONT_SIZE_HEIGHT);
            //文字在图片上的位置
            g2.drawString(note,margin, QRCODE_SIZE+font.getSize());
        }else{
            //这里的代码还没测试过
            g1.fillRect(0, QRCODE_SIZE, QRCODE_SIZE, QRCODE_SIZE+(height*conrow));
            //下面表示文件需要换行显示
            for (int i = 1; i < conrow; i++) {
                g2.drawString(note.substring((i-1)*zilen,i*zilen), margin, QRCODE_SIZE+(i*height)-(FONT_SIZE_HEIGHT/2)+10);
            }
            //g2.drawString(note.substring(0, 24),5, QRCODE_SIZE+font.getSize());
            g2.drawString(note.substring((conrow-1)*zilen), (((7 - note.substring((conrow-1)*zilen).length())*width)/2)+margin,
                    QRCODE_SIZE+(conrow*height)-(FONT_SIZE_HEIGHT/2)+10);
        }
        g1.drawImage(src, 0, 0, null);
        g1.dispose();
        g2.dispose();
        image = tag;
        image.flush();
        return image;
    }
}
